module bcd12 (
    input clk,
    input reset,
    input enable,
    output reg [7:0] q,
    output reg pm	// 0 for AM and 1 for PM
);
    // 12:00 AM = ???00:00?
	// 12:00 PM = ???12:00?
    // reset 
    // -> 12:00:00 AM -> 12:59:59 AM 
    // -> 01:00:00 AM -> 11:59:59 AM
    // -> 12:00:00 PM -> 12:59:59 PM 
    // -> 01:00:00 PM -> 11:59:59 PM 
    // -> 12:00:00 AM
    
    always @(posedge clk) begin
        if (reset) begin	// 12AM
            q <= 8'h12;
        	pm <= 1'b0;
        end
        else begin
            if (enable) begin
                if (q == 8'h12) // 12 -> 01
                    q <= 8'h01;
                else if (q == 8'h11) begin	// 11AM -> 12PM or 11PM -> 12AM
                    q <= 8'h12;
                    pm <= ~pm;
                end else if (q[3:0] == 4'h9)	// ?9
                    q <= {q[7:4] + 1'b1, 4'h0};
                else	// +1
                    q <= {q[7:4], q[3:0] + 1'b1};
            end
		end
    end
    
endmodule

// 00-59
module bcd59 (
	input clk,
    input reset,
    input enable,
    output reg [7:0] q
);
    
    always @(posedge clk) begin
        if (reset)
            q <= 8'h0;
        else begin
            if (enable) begin
                if (q == 8'h59)	// 59
                    q <= 8'h0;
                else if (q[3:0] == 4'h9) // ?9
                    q <= {q[7:4] + 1'b1, 4'h0};
                else	// +1
                    q <= {q[7:4], q[3:0] + 1'b1};
            end
        end
    end
    
endmodule

module clock(
    input clk,
    input reset,
    input ena,
    output pm,		// 0 for AM and 1 for PM
    output [7:0] hh,	// bcd 01-12
    output [7:0] mm,	// bcd 00-59
    output [7:0] ss);	// bcd 00-59
    
    wire ena_mm, ena_hh;
    
    assign ena_mm = (ss == 8'h59) && ena;		// ss = 59
    assign ena_hh = (mm == 8'h59) && ena_mm;	// mm == 59 && ss == 59
    
    bcd59 bcd_ss (.clk(clk), .reset(reset), .enable(ena),    .q(ss));
    bcd59 bcd_mm (.clk(clk), .reset(reset), .enable(ena_mm), .q(mm));
    bcd12 bcd_hh (.clk(clk), .reset(reset), .enable(ena_hh), .q(hh), .pm(pm));

endmodule